# -*- coding: utf-8 -*-


# cmap2owl -- Helper application to convert from concept maps to OWL ontologies
# Copyright (c) 2008-2013  Rodrigo Rizzi Starr
#  
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#  
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#  
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


'''
Generates a question with multiple options that can be turned on or off

@author: Rodrigo Rizzi Starr
@copyright: Copyright © 2008-2013 Rodrigo Rizzi Starr
@license: MIT License
@contact: rodrigo.starr@gmail.com
'''


import sys

# GTK+ imports
import pygtk
if not sys.platform == 'win32':
    pygtk.require('2.0')
try:
    import gtk
except:
    sys.exit(1)

from CMap2Prolog import assemblyQuery, assemblyText
from mapperQuestion import MapperQuestion
from log import log
log.debug("Loaded...")


class ToogleQuestion(MapperQuestion):
    "Implements a better way of checking if a disjunction group has changed"
    
    def __init__(self,
                 db,
                 data,
                 question = "",
                 helpFile = "basic",
                 startupState = True,
                 singularQuestion = "",
                 buttonLabels = ['Ok', 'None'],
                 ):

        MapperQuestion.__init__(self, db, data, question, helpFile = helpFile)
        self.singularQuestion = singularQuestion
        self.buttonLabels = buttonLabels
        self.choices = set()
        self.startupState = startupState
    
    def createData(self):
        "Updates the info that this class uses"
        self.updateQueryData()
        self.updateQueryIds()
        self.updateIds()
        self.updateChoices()
    
    def updateData(self):
        "Updates the info that this class uses"
        self.updateQueryData()
        self.updateQueryIds()
        self.updateIds()
        self.updateChoices()
        self.updateHighlights()
    
    def createMiddle(self):
        "Create the middle element that will hold the toogles"
        middle = gtk.VBox(spacing=2)
        middle.set_property("width-request", 300)
        
        return middle
    
    def updateChoices(self):
        "Update the choices variable with useful data"
        self.choices = self.ids
    
    def updateMiddle(self):
        "Cleans the list and updates the checkboxes to reflect the new status"
        
        if self.middle != None and len(self.choices) > 1:
            
            idsAlreadyDisplayed = set([])
            for widget in self.middle:
                if widget.id not in self.choices:
                    self.middle.remove(widget)
                else:
                    idsAlreadyDisplayed.add(widget.id)
                
            # Now adds the new ones
            for elId in (self.choices-idsAlreadyDisplayed):
                label = self.getLabel(elId)
                widget = gtk.CheckButton(label)
                widget.id = elId
                widget.connect("enter-notify-event", self.onEnter)
                widget.connect("leave-notify-event", self.onLeave)
                widget.connect("button-press-event", self.onButtonPress)
                widget.set_active(self.startupState)
                self.middle.add(widget)
                
            self.middle.show_all()
        elif self.middle != None and len(self.choices) == 1:
            for widget in self.middle:
                widget.set_active(True)
            self.middle.hide_all()
     
    def createButtons(self):
        "Returns a list with the buttons that will be used"
        bYes = gtk.Button(self.buttonLabels[0])
        bYes.connect("clicked", self.yes)
        bYes.connect("button-press-event", self.onButtonPress)
        
        bNo = gtk.Button(self.buttonLabels[1])
        bNo.connect("clicked", self.no)
        bNo.connect("button-press-event", self.onButtonPress)
        
        return [bYes, bNo]
    
    def updateButtons(self):
        "Changes the buttons according to the number of choices"
        if len(self.choices) == 1:
            self.buttons[0].set_label("Yes")
            self.buttons[1].set_label("No")
        else:
            self.buttons[0].set_label(self.buttonLabels[0])
            self.buttons[1].set_label(self.buttonLabels[1])

    def updateLabel(self):
        "Uses the correct label"
        if len(self.choices) == 1:
            label = assemblyText(self.singularQuestion, self.data, self.db)
        else:
            label = assemblyText(self.questionTemplate, self.data, self.db)
        if label != None:
            self.label.set_label(label)
    
    def createMenu(self):
        "Adds some options to the standard menu"
        
        # Gets the standar menu
        menu = MapperQuestion.createMenu(self)
        
        separator = gtk.SeparatorMenuItem()
        menu.append(separator)
        
        markAll = gtk.MenuItem("Select all")
        markAll.connect("activate", self.markAll)
        menu.append(markAll)
        
        unmarkAll = gtk.MenuItem("Deselect all")
        unmarkAll.connect("activate", self.unmarkAll)
        menu.append(unmarkAll)
        
        menu.show_all()
   
        return menu
    
    def getLabel(self, elId):
        "Returns the label for that id"
        
        label = list(self.db.query(assemblyQuery("label(%s, Label)", elId)))
        try:
            label = label[0]['Label']
        except IndexError:
            label = "Label not found"
        
        return label
    
    def getActiveIds(self):
        "Returns a set of the currently active ids"
        
        activeIds = set()
        if len(self.choices) == 1:
            activeIds = set(self.choices)
        else:
            for widget in self.middle:
                if widget.get_active():
                    activeIds.add(widget.id)
        return activeIds
    
    def markAll(self, menuItem = None):
        "Mark all items"
        for widget in self.middle:
            widget.set_active(True)
        
    def unmarkAll(self, menuItem = None):
        "Unmark all items"
        for widget in self.middle:
            widget.set_active(False)
        
    
